<?php
include_once 'animacao.php';
include_once 'link.php';
include_once 'musica.php';
include_once 'musica_animacao.php';
include_once 'tag.php';
include_once 'missa.php';
include_once 'musica_missa.php';

class DAO_PgSQL {
	
	private $id_usuario;
	
	function DAO_PgSQL() {
		date_default_timezone_set ('America/Recife');
		
		if (!isset($_SESSION)) {
			session_name("restauracao");
			session_start();
		}
		if (isset($_SESSION["id_usuario"])) {
			$this->id_usuario = $_SESSION["id_usuario"];
		}
		
		$host = "localhost";
		$usuario = "restaur";
		$senha = "cat3dral";
		$db = "restaur_restauracao";

		pg_connect("host=$host dbname=$db user=$usuario password=$senha");
	}
	
	function consulta_de_quem_eh($parte) {
		$consulta = pg_query("SELECT DISTINCT m.de_quem_eh
								FROM Musica m
								WHERE m.de_quem_eh LIKE '%$parte%' 
								ORDER BY m.de_quem_eh ASC");
		$retorno = array();
		while (list($de_quem_eh) = pg_fetch_array($consulta)) {
			$retorno[] = $de_quem_eh;
		}
		return $retorno;
	}
	
	function consulta_eventos($tipos_eventos, $nome_busca, $local_busca, $tipo_data, $data1, $data2, $musica_id, $descricao_busca, $ord_campo, $ord_direcao) {
		if (count($tipos_eventos) == 0) {
			return array();
		}
	
		$filtros = "";
		$separador = "WHERE ";
		if ($nome_busca != "") {
			$filtros .= $separador."LIMPAR_STRING(nome) LIKE '%' || LIMPAR_STRING('$nome_busca') || '%'";
			$separador = " AND ";
		}
		if ($local_busca != "") {
			$filtros .= $separador."LIMPAR_STRING(local) LIKE '%' || LIMPAR_STRING('$local_busca') || '%'";
			$separador = " AND ";
		}
		if ($descricao_busca != "") {
			$filtros .= $separador."LIMPAR_STRING(descricao) LIKE '%' || LIMPAR_STRING('$descricao_busca') || '%'";
			$separador = " AND ";
		}
		if ($tipo_data == "entre" && $data1 != "" && $data2 != "") {
			$filtros .= $separador."data_inicio >= TO_DATE('$data1','DD/MM/YYYY') 
										AND data_inicio <= TO_DATE('$data2','DD/MM/YYYY') 
										AND	CASE WHEN (data_fim IS NOT NULL) THEN data_fim <= TO_DATE('$data2', 'DD/MM/YYYY')
												ELSE TRUE 
											END";
			$separador = " AND ";
		}
		elseif ($tipo_data == "antes" && $data1 != "") {
			$filtros .= $separador."CASE WHEN (data_fim IS NOT NULL) THEN data_fim <= TO_DATE('$data1', 'DD/MM/YYYY')
										ELSE data_inicio <= TO_DATE('$data1','DD/MM/YYYY')
									END";
			$separador = " AND ";
		}
		elseif ($tipo_data == "depois" && $data1 != "") {
			$filtros .= $separador."data_inicio >= TO_DATE('$data1', 'DD/MM/YYYY')";
			$separador = " AND ";
		}
		if ($musica_id != "") {
			$filtros .= $separador."id IN (SELECT ma.animacao_id
												FROM Musica_Animacao ma, Animacao a 
												WHERE ma.animacao_id = a.id 
													AND ma.musica_id = $musica_id
											UNION
											SELECT mm.missa_id 
												FROM Musica_Missa mm, Missa m 
												WHERE mm.missa_id = m.id 
													AND mm.musica_id = $musica_id)";
			$separador = " AND ";
		}
		$filtro_tipo = "";
		$separador_tipo = "(";
		$fim_tipo = "";
		foreach ($tipos_eventos as $tipo) {
			$filtro_tipo .= $separador_tipo."tipo = '$tipo'";
			$separador_tipo = " OR ";
			$fim_tipo = ")";
		}
		$filtro_tipo .= $fim_tipo;
		$filtros .= $separador.$filtro_tipo;
		
		$query = "SELECT id 
					FROM Evento
					$filtros
					ORDER BY $ord_campo $ord_direcao";
		$consulta = pg_query($query);
		$eventos = array();
		while (list($id) = pg_fetch_array($consulta)) {
			$eventos[] = $this->get_evento($id);
		}
		return $eventos;
	}
	
	function consulta_musicas($texto, $ord_campo, $ord_direcao) {
		$texto = pg_escape_string($texto);
		$consulta = pg_query("SELECT m.id, m.titulo AS titulo, m.de_quem_eh AS de_quem_eh, m.quando_mexeu AS quando_mexeu 
									FROM Musica m  
									WHERE LIMPAR_STRING(m.titulo) LIKE '%' || LIMPAR_STRING('$texto') || '%' 
										OR LIMPAR_STRING(m.de_quem_eh) LIKE '%' || LIMPAR_STRING('$texto') || '%' 
										OR LIMPAR_STRING(m.letra) LIKE '%' || LIMPAR_STRING('$texto') || '%' 
										OR LIMPAR_STRING(m.observacoes) LIKE '%' || LIMPAR_STRING('$texto') || '%' 
								UNION
								SELECT m.id, m.titulo AS titulo, m.de_quem_eh AS de_quem_eh, m.quando_mexeu AS quando_mexeu  
									FROM Musica m, Tag t, Musica_Tag mt 
									WHERE LIMPAR_STRING(t.tag) LIKE '%' || LIMPAR_STRING('$texto') || '%'
										AND m.id = mt.musica_id 
										AND t.id = mt.tag_id
									ORDER BY $ord_campo $ord_direcao");
		$musicas = array();
		while (list($id) = pg_fetch_array($consulta)) {
			$musicas[] = $this->get_musica($id);
		}
		return $musicas;
	}
	
	function consulta_musicas_letra_inicial($letra, $ord_campo, $ord_direcao) {
		$letra = pg_escape_string($letra);
		$maiuscula = mb_strtoupper($letra);
		$minuscula = mb_strtolower($letra);
		$consulta = pg_query("SELECT m.id
								FROM Musica m  
								WHERE m.titulo LIKE '$maiuscula%'
									OR m.titulo LIKE '$minuscula%' 
								ORDER BY m.$ord_campo $ord_direcao");
		$musicas = array();
		while (list($id) = pg_fetch_array($consulta)) {
			$musicas[] = $this->get_musica($id);
		}
		return $musicas;
	}
	
	function consulta_musicas_titulo($texto) {
		$texto = pg_escape_string($texto);
		$consulta = pg_query("SELECT m.id, m.titulo AS titulo
								FROM Musica m  
								WHERE LIMPAR_STRING(m.titulo) LIKE '%' || LIMPAR_STRING('$texto') || '%' 
								ORDER BY titulo ASC");
		$musicas = array();
		while (list($id) = pg_fetch_array($consulta)) {
			$musicas[] = $this->get_musica($id);
		}
		return $musicas;
	}
	
	function consulta_tags($parte_tag) {
		$consulta = pg_query("SELECT t.id, t.tag
								FROM Tag t 
								WHERE t.tag LIKE '%$parte_tag%' 
								ORDER BY t.tag ASC");
		$retorno = array();
		while (list($id, $tag) = pg_fetch_array($consulta)) {
			$objeto_tag = new Tag();
			$objeto_tag->set_id($id);
			$objeto_tag->set_tag($tag);
			$retorno[] = $objeto_tag;
		}
		return $retorno;
	}
	
	function consulta_tipos_links($parte) {
		$consulta = pg_query("SELECT DISTINCT l.tipo
								FROM Link l 
								WHERE l.tipo LIKE '%$parte%' 
								ORDER BY l.tipo ASC");
		$retorno = array();
		while (list($tipo) = pg_fetch_array($consulta)) {
			$retorno[] = $tipo;
		}
		return $retorno;
	}
	
	function consulta_ultimos_5_eventos($ord_campo, $ord_direcao) {
		$consulta = pg_query("SELECT e.id
								FROM (SELECT * 
										FROM Evento 
										ORDER BY data_inicio DESC 
										LIMIT 5) e
								ORDER BY e.$ord_campo $ord_direcao");
		$eventos = array();
		while (list($id) = pg_fetch_array($consulta)) {
			$eventos[] = $this->get_evento($id);
		}
		return $eventos;
	}
	
	function consulta_ultimas_5_musicas($ord_campo, $ord_direcao) {
		$consulta = pg_query("SELECT m.id
								FROM (SELECT * 
										FROM Musica 
										ORDER BY quando_mexeu DESC 
										LIMIT 5) m
								ORDER BY m.$ord_campo $ord_direcao");
		$musicas = array();
		while (list($id) = pg_fetch_array($consulta)) {
			$musicas[] = $this->get_musica($id);
		}
		return $musicas;
	}
	
	function deletar_evento($evento) {
		$id = pg_escape_string($evento->get_id());
		
		$deletar = pg_query("DELETE FROM Animacao
									WHERE id = $id;
								DELETE FROM Missa 
									WHERE id = $id;");
		if (!$deletar) {
			throw new Exception("Erro ao deletar objeto Evento: ".pg_last_error());
		}
	}
	
	function deletar_link($link) {
		if (get_class($link) != "Link") {
			throw new Exception("Impossível deletar objeto - parâmetro precisa ser da classe Link");
		}
	
		$id = pg_escape_string($link->get_id());
	
		$deletar = pg_query("DELETE FROM Link WHERE id=$id");
		if (!$deletar) {
			throw new Exception("Erro ao deletar objeto Link: ".pg_last_error());
		}
	}
	
	function deletar_musica($musica) {
		if (get_class($musica) != "Musica") {
			throw new Exception("Impossível deletar objeto - parâmetro precisa ser da classe Musica");
		}
	
		$id = pg_escape_string($musica->get_id());
	
		$deletar = pg_query("DELETE FROM Musica WHERE id=$id");
		if (!$deletar) {
			throw new Exception("Erro ao deletar objeto Musica: ".pg_last_error());
		}
		else {
			$this->remover_tags_orfas();
		}
		
	}
	
	function deletar_todos_links_de_musica($musica) {
		if (get_class($musica) != "Musica") {
			throw new Exception("Impossível deletar objeto - parâmetro precisa ser da classe Musica");
		}
	
		$id = pg_escape_string($musica->get_id());
		$deletar = pg_query("DELETE FROM Link WHERE musica_id=$id");
		if (!$deletar) {
			throw new Exception("Erro ao deletar links de música: ".pg_last_error());
		}
	}
	
	function descricao_de_evento_contem_busca($texto_busca, $evento) {
		$texto = pg_escape_string($texto_busca);
		$id = pg_escape_string($evento->get_id());
		$consulta = pg_query("SELECT *
								FROM Evento e 
								WHERE LIMPAR_STRING(e.descricao) LIKE '%' || LIMPAR_STRING('$texto') || '%' 
									AND id = $id");
		return pg_num_rows($consulta) > 0;
	}
	
	function get_animacao($animacao_id) {
		$animacao_id = pg_escape_string($animacao_id);
		
		$consulta = pg_query("SELECT a.id, a.nome, a.local, TO_CHAR(a.data_inicio, 'DD/MM/YYYY') AS data_inicio, TO_CHAR(a.data_fim, 'DD/MM/YYYY') AS data_fim, a.descricao, fb.quem_eh AS quem_mexeu, EXTRACT(EPOCH FROM a.quando_mexeu) AS quando_mexeu 
								FROM Animacao a, ID_Facebook fb
								WHERE a.id = $animacao_id
									AND a.quem_mexeu = fb.id_facebook");
	
		if (pg_num_rows($consulta) == 0) {
			throw new Exception("Não foi encontrado registro de animação com ID $animacao_id");
		}
		else if (pg_num_rows($consulta) > 1) {
			throw new Exception("Consulta de animação inválida com ID $animacao_id");
		}
	
		$animacao = new Animacao();
		$animacao->setar_atributos_array(pg_fetch_assoc($consulta));
		$animacao->set_data_inicio($animacao->get_data_inicio());
		$animacao->set_data_fim($animacao->get_data_fim());
	
		$consulta_musicas = pg_query("SELECT ma.musica_id, ma.ordem 
										FROM Musica_Animacao ma  
										WHERE ma.animacao_id = $animacao_id  
										ORDER BY ma.ordem ASC");
		while (list($musica_id, $ordem) = pg_fetch_array($consulta_musicas)) {
			$animacao->adicionar_em_colecao("musicas_animacao", $this->get_musica_animacao($musica_id, $animacao->get_id(), $ordem));
		}
		
		return $animacao;
	}
	
	function get_evento($evento_id) {
		$evento_id = pg_escape_string($evento_id);
		
		$consulta = pg_query("SELECT e.id, e.tipo
								FROM Evento e
								WHERE e.id=$evento_id");
		
		if (pg_num_rows($consulta) == 0) {
			throw new Exception("Não foi encontrado registro de evento com ID $evento_id");
		}
		else if (pg_num_rows($consulta) > 1) {
			throw new Exception("Consulta de evento inválida com ID $evento_id");
		}
		
		list($id, $tipo) = pg_fetch_array($consulta);
		if ($tipo == "Animação") {
			return $this->get_animacao($id);
		}
		elseif ($tipo == "Missa") {
			return $this->get_missa($id);
		}
		
	}

	function get_link($link_id) {
		$link_id = pg_escape_string($link_id);
		$consulta = pg_query("SELECT l.id, l.tipo, l.url, l.musica_id
								FROM Link l 
								WHERE l.id = $link_id");
	
		if (pg_num_rows($consulta) == 0) {
			throw new Exception("Não foi encontrado registro de link com ID $link_id");
		}
		else if (pg_num_rows($consulta) > 1) {
			throw new Exception("Consulta de link inválida com ID $link_id");
		}
	
		$link = new Link();
		$link->setar_atributos_array(pg_fetch_assoc($consulta));
	
		return $link;
	}
	
	function get_missa($missa_id) {
		$missa_id = pg_escape_string($missa_id);
	
		$consulta = pg_query("SELECT m.id, m.nome, m.local, TO_CHAR(m.data_inicio, 'DD/MM/YYYY') AS data_inicio, TO_CHAR(m.data_fim, 'DD/MM/YYYY') AS data_fim, m.descricao, tm.tipo AS tipo_missa, fb.quem_eh AS quem_mexeu, EXTRACT(EPOCH FROM m.quando_mexeu) AS quando_mexeu 
								FROM Missa m, Tipo_Missa tm, ID_Facebook fb  
								WHERE m.id = $missa_id 
									AND m.tipo_id = tm.id
									AND m.quem_mexeu = fb.id_facebook");
	
		if (pg_num_rows($consulta) == 0) {
			throw new Exception("Não foi encontrado registro de missa com ID $missa_id");
		}
		else if (pg_num_rows($consulta) > 1) {
			throw new Exception("Consulta de missa inválida com ID $missa_id");
		}
	
		$missa = new Missa();
		$missa->setar_atributos_array(pg_fetch_assoc($consulta));
		$missa->set_tipo_missa($missa->get_tipo_missa());
		$missa->set_data_inicio($missa->get_data_inicio());
		$missa->set_data_fim($missa->get_data_fim());
	
		$consulta_musicas = pg_query("SELECT mm.musica_id, mm.parte_missa 
										FROM Musica_Missa mm   
										WHERE mm.missa_id = $missa_id");
		while (list($musica_id, $parte_missa) = pg_fetch_array($consulta_musicas)) {
			$missa->adicionar_musica($this->get_musica_missa($musica_id, $missa->get_id(), $parte_missa));
		}
	
		return $missa;
	}
	
	function get_musica($musica_id) {
		$musica_id = pg_escape_string($musica_id);
		$consulta = pg_query("SELECT m.id, m.titulo, m.de_quem_eh, m.letra, m.tom_padrao, m.observacoes, fb.quem_eh AS quem_mexeu, EXTRACT(EPOCH FROM m.quando_mexeu) AS quando_mexeu  
								FROM Musica m, ID_Facebook fb 
								WHERE m.id = $musica_id
									AND m.quem_mexeu = fb.id_facebook");
		
		if (pg_num_rows($consulta) == 0) {
			throw new Exception("Não foi encontrado registro de música com ID $musica_id");
		}
		else if (pg_num_rows($consulta) > 1) {
			throw new Exception("Consulta de música inválida com ID $musica_id");
		}
		
		$musica = new Musica();
		$musica->setar_atributos_array(pg_fetch_assoc($consulta));
		
		$consulta_links = pg_query("SELECT l.id 
										FROM Link l
										WHERE l.musica_id = $musica_id");
		while (list($link_id) = pg_fetch_array($consulta_links)) {
			$musica->adicionar_em_colecao("links", $this->get_link($link_id));
		}
		
		$consulta_tags = pg_query("SELECT mt.tag_id
									FROM Musica_Tag mt
									WHERE mt.musica_id = $musica_id");
		while (list($tag_id) = pg_fetch_array($consulta_tags)) {
			$musica->adicionar_em_colecao("tags", $this->get_tag($tag_id));
		}
		
		return $musica;
	}
	
	function get_musica_animacao($musica_id, $animacao_id, $ordem) {
		$musica_id = pg_escape_string($musica_id);
		$animacao_id = pg_escape_string($animacao_id);
		$consulta = pg_query("SELECT ma.musica_id, ma.animacao_id, ma.tom, ma.quem_canta, ma.ordem  
								FROM Musica_Animacao ma  
								WHERE ma.musica_id = $musica_id 
									AND ma.animacao_id = $animacao_id
									AND ma.ordem = $ordem");
		
		if (pg_num_rows($consulta) == 0) {
			throw new Exception("Não foi encontrado registro de relacionamento música-animação com IDs de música $musica_id e animação $animacao_id");
		}
		if (pg_num_rows($consulta) > 1) {
			throw new Exception("Consulta inválida para relacionamento música-animação com IDs de música $musica_id e animação $animacao_id");
		}
		
		$musica_animacao = new Musica_Animacao();
		$musica_animacao->setar_atributos_array(pg_fetch_assoc($consulta));
		$musica_animacao->set_musica($this->get_musica($musica_animacao->musica_id));
		
		return $musica_animacao;
	}
	
	function get_musica_missa($musica_id, $missa_id, $parte_missa) {
		$musica_id = pg_escape_string($musica_id);
		$missa_id = pg_escape_string($missa_id);

		$consulta = pg_query("SELECT mm.musica_id, mm.missa_id, mm.tom, mm.parte_missa
								FROM Musica_Missa mm  
								WHERE mm.musica_id = $musica_id 
									AND mm.missa_id = $missa_id
									AND mm.parte_missa = '$parte_missa'");
	
		if (pg_num_rows($consulta) == 0) {
			throw new Exception("Não foi encontrado registro de relacionamento música-missa com IDs de música $musica_id e missa $missa_id");
		}
		if (pg_num_rows($consulta) > 1) {
			throw new Exception("Consulta inválida para relacionamento música-missa com IDs de música $musica_id e missa $missa_id");
		}
	
		$musica_missa = new Musica_Missa();
		$musica_missa->setar_atributos_array(pg_fetch_assoc($consulta));
		$musica_missa->set_musica($this->get_musica($musica_missa->musica_id));
	
		return $musica_missa;
	}
	
	function get_tag($tag_id) {
		$tag_id = pg_escape_string($tag_id);
		$consulta = pg_query("SELECT t.id, t.tag 
								FROM Tag t 
								WHERE t.id = $tag_id");
	
		if (pg_num_rows($consulta) == 0) {
			throw new Exception("Não foi encontrado registro de tag com ID $tag_id");
		}
		else if (pg_num_rows($consulta) > 1) {
			throw new Exception("Consulta de tag inválida com ID $tag_id");
		}
	
		$tag = new Tag();
		$tag->setar_atributos_array(pg_fetch_assoc($consulta));
		
		return $tag;
	}
	
	function get_tag_texto($tag) {
		$tag = pg_escape_string($tag);
		$consulta = pg_query("SELECT t.id 
								FROM Tag t
								WHERE t.tag = '$tag'");
		if (pg_num_rows($consulta) == 0) {
			throw new Exception("Não foi encontrado registro de tag $tag");
		}
		
		list($tag_id) = pg_fetch_array($consulta);
		
		return $this->get_tag($tag_id);
	}
	
	function get_todas_musicas() {
		$consulta = pg_query("SELECT m.id 
								FROM Musica m 
								ORDER BY m.titulo ASC,
									m.de_quem_eh ASC");
		$musicas = array();
		while (list($id) = pg_fetch_array($consulta)) {
			$musicas[] = $this->get_musica($id);
		}
		return $musicas;
	}
	
	function id_facebook_eh_valido($id_facebook) {
		$consulta = pg_query("SELECT i.* 
								FROM ID_Facebook i 
								WHERE i.id_facebook = '$id_facebook'");
		return pg_num_rows($consulta) == 1;
	}
	
	function observacao_de_musica_contem_busca($texto_busca, $musica) {
		if (get_class($musica) != "Musica") {
			throw new Exception("Impossível buscar em observação de música - parâmetros precisam ser das classes String, Musica");
		}
	
		$texto = pg_escape_string($texto_busca);
		$id = pg_escape_string($musica->get_id());
		$consulta = pg_query("SELECT *
								FROM Musica m  
								WHERE LIMPAR_STRING(m.observacoes) LIKE '%' || LIMPAR_STRING('$texto') || '%' 
									AND id = $id");
		return pg_num_rows($consulta) > 0;
	}

	function quantas_animacoes() {
		$consulta = pg_query("SELECT * FROM Animacao a");
		return pg_num_rows($consulta);
	}
	
	function quantas_missas() {
		$consulta = pg_query("SELECT * FROM Missa m");
		return pg_num_rows($consulta);
	}
	
	function quantas_musicas() {
		$consulta = pg_query("SELECT * FROM Musica m");
		return pg_num_rows($consulta);
	}
	
	function quem_mais_cantou() {
		$consulta = pg_query("SELECT COUNT(*), ma.quem_canta
								FROM Musica_Animacao ma 
								WHERE ma.quem_canta != ''
								GROUP BY ma.quem_canta
								HAVING COUNT(*) = (SELECT MAX(x.quant)
													FROM (SELECT COUNT(*) AS quant, ma.quem_canta
															FROM Musica_Animacao ma
															WHERE ma.quem_canta != ''
															GROUP BY ma.quem_canta) x)
								ORDER BY ma.quem_canta ASC");
		$retorno = array();
		while (list($quantas, $quem_mais_canta) = pg_fetch_array($consulta)) {
			$retorno[] = array(
							'quem_canta' => $quem_mais_canta,
							'quantas' => $quantas);
		}
		return $retorno;
	}
	
	function remover_tag_de_musica($tag, $musica) {
		if (get_class($tag) != "Tag" || get_class($musica) != "Musica") {
			throw new Exception("Impossível remover tag - parâmetros precisam ser das classes Tag, Musica");
		}
		
		$tag_id = pg_escape_string($tag->get_id());
		$musica_id = pg_escape_string($musica->get_id());
		$remover = pg_query("DELETE FROM Musica_Tag WHERE tag_id = $tag_id AND musica_id = $musica_id");
		if (!$remover) {
			throw new Exception("Erro ao remover tag de música: ".pg_last_error());
		}
		
		$this->remover_tags_orfas();
	}
	
	function remover_todas_tags_de_musica($musica) {
		if (get_class($musica) != "Musica") {
			throw new Exception("Impossível remover tags - parâmetro precisa ser da classe Musica");
		}
		
		$id = pg_escape_string($musica->get_id());
		$remover = pg_query("DELETE FROM Musica_Tag WHERE musica_id = $id");
		if (!$remover) {
			throw new Exception("Erro ao remover tags de música: ".pg_last_error());
		}
		
		$this->remover_tags_orfas();
	}
	
	function remover_tags_orfas() {
		$consulta = pg_query("DELETE FROM Tag
								WHERE Tag.id NOT IN (SELECT mt.tag_id 
													FROM Musica_Tag mt)");
		if (!$consulta) {
			throw new Exception("Erro ao remover tags órfãs: ".pg_last_error());
		}
	}

	function salvar_animacao($animacao) {
		if (get_class($animacao) != "Animacao") {
			throw new Exception("Impossível salvar objeto - parâmetro precisa ser da classe Animacao");
		}
		
		if ($animacao->get_id()) {
			$id = pg_escape_string($animacao->get_id());
		}
		else {
			$id = "null";
		}
		
		$nome = pg_escape_string($animacao->get_nome());
		$local = pg_escape_string($animacao->get_local());
		$data_inicio = pg_escape_string($animacao->get_data_inicio_bd());
		$data_fim = "'".pg_escape_string($animacao->get_data_fim_bd())."'";
		if ($data_fim == "''") {
			$data_fim = "NULL";
		}
		$descricao = pg_escape_string($animacao->get_descricao());
		
		$consulta_se_existe = pg_query("SELECT * 
											FROM Animacao a 
											WHERE a.id = $id");
		if (pg_num_rows($consulta_se_existe)) {
			$salvar = pg_query(("UPDATE Animacao 
									SET nome = '$nome', 
										local = '$local', 
										data_inicio = '$data_inicio', 
										data_fim = $data_fim, 
										descricao = '$descricao',
										quem_mexeu = '".$this->id_usuario."',
										quando_mexeu = NOW()
									WHERE id = $id"));
		}
		else {
			$salvar = pg_query("INSERT INTO Animacao (nome, local, data_inicio, data_fim, descricao, quem_mexeu) VALUES (
									'$nome', 
									'$local', 
									'$data_inicio', 
									$data_fim, 
									'$descricao', 
									'".$this->id_usuario."')");
			$consulta_id = pg_query("SELECT lastval()");
			list($ultimo_id) = pg_fetch_array($consulta_id);
			$animacao->set_id($ultimo_id);
		}
		if (!$salvar) {
			throw new Exception("Erro ao salvar objeto Animacao: ".pg_last_error());
		}

		$remover_relacionamentos_com_musica = pg_query("DELETE FROM Musica_Animacao 
															WHERE animacao_id = ".$animacao->get_id());
		if (isset($animacao->id_musicas_adicionar)) {
			for ($i = 0; $i < count($animacao->id_musicas_adicionar); $i++) {
				$musica_id = $animacao->id_musicas_adicionar[$i];
				$tom = $animacao->tons_adicionar[$i];
				$quem_canta = $animacao->quem_canta_adicionar[$i];
				$inserir = pg_query("INSERT INTO Musica_Animacao (musica_id, animacao_id, tom, quem_canta, ordem) VALUES (
										$musica_id, 
										".$animacao->get_id().", 
										'$tom', 
										'$quem_canta', 
										".($i + 1).")");
				if (!$inserir) {
					throw new Exception("Erro ao salvar relacionamento Musica-Animacao: ".pg_last_error());
				}
				$musica = new Musica();
				$musica->set_id($musica_id);
				$tag = new Tag();
				$tag->set_tag("Animação");
				$this->salvar_tag($tag, $musica);
			}
		}
	}
	
	function salvar_missa($missa) {
		if (get_class($missa) != "Missa") {
			throw new Exception("Impossível salvar objeto - parâmetro precisa ser da classe Missa");
		}
	
		if ($missa->get_id()) {
			$id = pg_escape_string($missa->get_id());
		}
		else {
			$id = "null";
		}
	
		$nome = pg_escape_string($missa->get_nome());
		$local = pg_escape_string($missa->get_local());
		$data_inicio = pg_escape_string($missa->get_data_inicio_bd());
		$data_fim = "'".pg_escape_string($missa->get_data_fim_bd())."'";
		if ($data_fim == "''") {
			$data_fim = "NULL";
		}
		$descricao = pg_escape_string($missa->get_descricao());
		$tipo_missa = pg_escape_string($missa->get_tipo_missa());
	
		$consulta_se_existe = pg_query("SELECT *
											FROM Missa m 
											WHERE m.id = $id");
		if (pg_num_rows($consulta_se_existe)) {
			$salvar = pg_query(("UPDATE Missa  
									SET nome = '$nome', 
										local = '$local', 
										data_inicio = '$data_inicio', 
										data_fim = $data_fim, 
										descricao = '$descricao',
										tipo_id = (SELECT tm.id 
													FROM Tipo_Missa tm 
													WHERE tm.tipo = '$tipo_missa'),
										quem_mexeu = '".$this->id_usuario."',
										quando_mexeu = NOW() 
									WHERE id = $id"));
		}
		else {
			$salvar = pg_query("INSERT INTO Missa (nome, local, data_inicio, data_fim, descricao, tipo_id, quem_mexeu) VALUES (
									'$nome', 
									'$local', 
									'$data_inicio', 
									$data_fim,
									'$descricao', 
									(SELECT tm.id 
										FROM Tipo_Missa tm 
										WHERE tm.tipo = '$tipo_missa'),
									'".$this->id_usuario."')");
			$consulta_id = pg_query("SELECT lastval()");
			list($ultimo_id) = pg_fetch_array($consulta_id);
			$missa->set_id($ultimo_id);
		}
		if (!$salvar) {
			throw new Exception("Erro ao salvar objeto Missa: ".pg_last_error());
		}
	
		$remover_relacionamentos_com_musica = pg_query("DELETE FROM Musica_Missa
															WHERE missa_id = ".$missa->get_id());
		if (isset($missa->id_musicas_adicionar)) {
			for ($i = 0; $i < count($missa->id_musicas_adicionar); $i++) {
				$musica_id = $missa->id_musicas_adicionar[$i];
				if ($musica_id != "") {
					$tom = $missa->tons_adicionar[$i];
					$parte_missa = $missa->partes_adicionar[$i];
					$inserir = pg_query("INSERT INTO Musica_Missa (musica_id, missa_id, tom, parte_missa) VALUES (
											$musica_id,
											".$missa->get_id().", 
											'$tom', 
											'$parte_missa')");
					if (!$inserir) {
						throw new Exception("Erro ao salvar relacionamento Musica-Missa: ".pg_last_error());
					}
					$musica = new Musica();
					$musica->set_id($musica_id);
					$tag = new Tag();
					$tag->set_tag(Missa::label($parte_missa));
					$this->salvar_tag($tag, $musica);
				}
			}
		}
	}
	
	function salvar_musica($musica) {
		if (get_class($musica) != "Musica") {
			throw new Exception("Impossível salvar objeto - parâmetro precisa ser da classe Musica");
		}
	
		if ($musica->get_id()) {
			$id = pg_escape_string($musica->get_id());
		}
		else {
			$id = "null";
		}
	
		$titulo = pg_escape_string($musica->get_titulo());
		$de_quem_eh = pg_escape_string($musica->get_de_quem_eh());
		$letra = pg_escape_string($musica->get_letra());
		$tom_padrao = pg_escape_string($musica->get_tom_padrao());
		$observacoes = pg_escape_string($musica->get_observacoes());
	
		$consulta_se_existe = pg_query("SELECT *
											FROM Musica m 
											WHERE m.id = $id");
		if (pg_num_rows($consulta_se_existe) == 1) {
			$salvar = pg_query("UPDATE Musica 
									SET	titulo = '$titulo', 
										de_quem_eh = '$de_quem_eh', 
										letra = '$letra', 
										tom_padrao = '$tom_padrao', 
										observacoes = '$observacoes',
										quem_mexeu = '".$this->id_usuario."',
										quando_mexeu = NOW() 
									WHERE id = $id");
		}
		else {
			$salvar = pg_query("INSERT INTO Musica (titulo, de_quem_eh, letra, tom_padrao, observacoes, quem_mexeu) VALUES (
									'$titulo',
									'$de_quem_eh', 
									'$letra', 
									'$tom_padrao', 
									'$observacoes', 
									'".$this->id_usuario."')");
			$consulta_id = pg_query("SELECT lastval()");
			list($ultimo_id) = pg_fetch_array($consulta_id);
			$musica->set_id($ultimo_id);
		}
	
		if (!$salvar) {
			throw new Exception("Erro ao salvar objeto Musica: ".pg_last_error());
		}
	
		if (isset($musica->id_links_a_deletar)) {
			foreach ($musica->id_links_a_deletar as $id_link) {
				$link = new Link();
				$link->set_id($id_link);
				$this->deletar_link($link);
				$musica->remover_de_colecao("links", $link);
			}
		}
		if (isset($musica->links_a_adicionar)) {
			foreach ($musica->links_a_adicionar as $link) {
				$link->set_musica_id($musica->get_id());
				$this->salvar_link($link);
			}
		}
	
		if (isset($musica->id_tags_a_remover)) {
			foreach ($musica->id_tags_a_remover as $id_tag) {
				$tag = new Tag();
				$tag->set_id($id_tag);
				$this->remover_tag_de_musica($tag, $musica);
				$musica->remover_de_colecao("tags", $tag);
			}
		}
		if (isset($musica->tags_a_adicionar)) {
			foreach ($musica->tags_a_adicionar as $tag) {
				$this->salvar_tag($tag, $musica);
			}
		}
		
		$this->remover_tags_orfas();
	}
	
	function salvar_link($link) {
		if (get_class($link) != "Link") {
			throw new Exception("Impossível salvar objeto - parâmetro precisa ser da classe Link");
		}
		$tipo = pg_escape_string($link->get_tipo());
		$url = pg_escape_string($link->get_url());
		$musica_id = pg_escape_string($link->get_musica_id());
		$salvar = pg_query("INSERT INTO Link (tipo, url, musica_id) VALUES (
								'$tipo', 
								'$url', 
		$musica_id)");
		if (!$salvar) {
			throw new Exception("Erro ao salvar objeto Link: ".pg_last_error());
		}
	}

	function salvar_tag($tag, $musica) {
		if (get_class($tag) != "Tag" || get_class($musica) != "Musica") {
			throw new Exception("Impossível salvar objeto - parâmetros precisam ser das classes Tag, Musica");
		}
		$tag_tag = pg_escape_string($tag->get_tag());

		$consulta_existe = pg_query("SELECT t.id
										FROM Tag t 
										WHERE t.tag = '$tag_tag'");
		if (pg_num_rows($consulta_existe) == 0) {
			$criar_tag = pg_query("INSERT INTO Tag (tag) VALUES (
									'$tag_tag')");
			if (!$criar_tag) {
				throw new Exception("Erro ao criar objeto Tag: ".pg_last_error());
			}
			$consulta_id = pg_query("SELECT lastval()");
			list($ultimo_id) = pg_fetch_array($consulta_id);
			$id = $ultimo_id;
		}
		else {
			list($id) = pg_fetch_array($consulta_existe);
		}
		$tag->set_id($id);

		$tag_id = pg_escape_string($tag->get_id());
		$musica_id = pg_escape_string($musica->get_id());

		$consulta_existe_relacionamento = pg_query("SELECT *
														FROM Musica_Tag
														WHERE tag_id = $tag_id 
															AND musica_id = $musica_id");
		if (pg_num_rows($consulta_existe_relacionamento) == 0) {
			$inserir_relacionamento = pg_query("INSERT INTO Musica_Tag (tag_id, musica_id) VALUES (
													$tag_id,
													$musica_id)");
			if (!$inserir_relacionamento) {
				throw new Exception("Erro ao criar relacionamento Tag-Musica: ".pg_last_error());
			}

		}
	}

}
?>